<template>
  <div class="city-list">
    <div class="city-list-catalog">
      <el-tabs
        ref="tabs"
        v-model="activeName"
        tab-position="left"
        @tab-click="tabClick"
      >
        <el-tab-pane
          v-for="{ name, key } in citys"
          :label="name"
          :name="key"
          :key="key"
        ></el-tab-pane>
      </el-tabs>
    </div>
    <div ref="content" class="city-list-content">
      <el-alert
        v-if="warning"
        :title="warning"
        type="warning"
        show-icon
        class="warning"
      >
      </el-alert>
      <div
        v-for="{ code, name, action, key, children } in citys"
        :key="`g-${key}`"
        :data-section="key"
        class="city-list-content-section c-item"
      >
        <!-- <div class="city-list-content-section-title">{{ name }}</div> -->
        <div class="city-list-content-section-title">
          <a
            :class="`${action ? 'hover' : ''} ${
              selectedCity == code ? 'selected' : ''
            }`"
            :data-code="code"
            :data-name="name"
            :data-action="action"
            @click="select"
            >{{ name }}</a
          >
        </div>
        <div class="city-list-content-section-content">
          <a
            v-for="{
              code: ccode,
              key: ckey,
              name: cname,
              action: caction,
            } in children"
            :key="ckey"
            :class="`city-list-content-section-item ${caction ? 'hover' : ''} ${
              selectedCity == ccode ? 'selected' : ''
            }`"
            :data-code="ccode"
            :data-name="cname"
            :data-action="caction"
            @click="select"
            >{{ cname }}</a
          >
        </div>
      </div>
    </div>
    <div v-if="citys.length == 0" class="city-list-no-data">
      <svg-icon icon-class="no-data"></svg-icon>
      <div class="city-list-no-data-text">无搜索结果</div>
    </div>
  </div>
</template>
<script>
import ScrollContainer from "./ScrollContainer.js";
import { forEach } from "../../utils";

export default {
  name: "CityList",
  props: {
    selected: {
      type: Object,
      default: { code: "", name: "" },
    },
    // {name, code, children}
    citys: {
      type: Array,
      default: [{ code: "AA", name: "AA", key: "1", children: [] }],
    },
    defaultActiveTab: {
      type: String,
      default: "AA",
    },
    warning: {
      type: String,
      default: "",
    },
  },
  components: {},
  data() {
    return {
      offset: 48,
      // innerCitys: [
      //     {
      //         name: "",
      //         code: "",
      //         children: [{}],
      //     },
      // ],
      activeName: this.defaultActiveTab,
      selectedCity: this.selected?.code,
      duration: 600,
      currentScrollTop: 1,
      moving: false,
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.initTabs();
      this.initScroll();
    });
  },
  beforeDestroy() {
    this.scroll && this.scroll.removeScrollListener();
  },
  methods: {
    initScroll() {
      this.scroll = new ScrollContainer(this.$refs.content);
      this.scroll.addScrollListener(this.onScroll);
    },
    initTabs() {
      //el-tabs__active-bar
      const checkTabs = () => {
        if (this.$refs.tabs.panes?.length == 0) {
          window.requestAnimationFrame(checkTabs);
        } else {
          // 强制初始化赋值高度
          this.$refs.tabs.$el.querySelector(
            ".el-tabs__active-bar"
          ).style.height = "32px";
        }
      };
      checkTabs();
    },
    onScroll(event) {
      this.currentScrollTop = this.scroll.getScrollTop();
      const currentItem = this.getItemInside();
      if (this.moving || !currentItem) return;

      this.activeName = currentItem.dataset.section;
    },
    getItemInside() {
      let currentItem;
      let scrollTop = null;
      const elements = this.$el.querySelectorAll(".c-item");
      forEach(elements, (section, index) => {
        if (!section) {
          return;
        }
        if (scrollTop === null) {
          scrollTop = this.scroll.getScrollTop();
        }

        const targetOffsetTop = this.getOffsetTop(section) - this.offset;
        const isScreenPastSectionStart = scrollTop >= targetOffsetTop;
        const isScreenBeforeSectionEnd =
          scrollTop < targetOffsetTop + section.offsetHeight;
        const isScreenInsideSection =
          isScreenPastSectionStart && isScreenBeforeSectionEnd;

        if (isScreenInsideSection) currentItem = section;
      });

      return currentItem;
    },
    getItemInsideWindow() {
      let currentItem;
      let scrollTop = null;
      const elements = this.$el.querySelectorAll(".c-item");
      forEach(elements, (section, index) => {
        if (!section) {
          return;
        }
        if (scrollTop === null) {
          scrollTop = this.scroll.getScrollTop();
        }

        const distanceFromTop = this.scroll.getDistanceFromTop();
        const targetOffsetTop =
          this.getOffsetTop(section) - this.offset - scrollTop;
        const isScreenPastSectionStart = distanceFromTop >= targetOffsetTop;
        const isScreenBeforeSectionEnd =
          distanceFromTop < targetOffsetTop + section.offsetHeight;
        const isScreenInsideSection =
          isScreenPastSectionStart && isScreenBeforeSectionEnd;

        if (isScreenInsideSection) currentItem = section;
      });

      return currentItem;
    },
    getSectionSelector(element) {
      if (element.dataset.section) return element.dataset.section;
      if (element.hash) return `#${decodeURI(element.hash.substr(1))}`;

      return "";
    },
    getOffsetTop(element) {
      // let yPosition = 0;
      // let nextElement = element;

      // while (nextElement) {
      //     yPosition += nextElement.offsetTop;
      //     nextElement = nextElement.offsetParent;
      // }

      // if (this.scroll.getOffsetTop()) {
      //     yPosition -= this.scroll.getOffsetTop();
      // }

      // return yPosition;
      return element.offsetTop;
    },
    scrollTo(target, motion) {
      return new Promise((resolve) => {
        this.moving = true;
        const targetDistanceFromTop = this.getOffsetTop(target) - this.offset;

        if (motion) {
          this.scroll.scrollToWithMotion(0, targetDistanceFromTop);
          setTimeout(() => resolve(), 1000);
        } else {
          this.scroll.scrollTo(0, targetDistanceFromTop);
          resolve();
        }
      });
    },
    tabClick(e) {
      this.scrollTo(
        this.$el.querySelector(`div[data-section="${e.name}"]`),
        true
      ).then(() => {
        this.moving = false;
      });
    },
    select(e) {
      if (!e.target.dataset.action) return;

      // console.log("select code: ", e.target.dataset.code || "");
      this.selectedCity = e.target.dataset.code;
      this.$emit("update:selected", {
        name: e.target.dataset.name,
        code: e.target.dataset.code || "",
      });
      this.$emit("change", {
        name: e.target.dataset.name,
        code: e.target.dataset.code || "",
      });
    },
    show() {
      // 滑动条保持原来的位置
      this.scroll.scrollTo(0, this.currentScrollTop);
    },
  },
  watch: {
    selected(nv, ov) {
      if (nv.code == "") {
        this.selectedCity = nv.code;
        this.activeName = this.defaultActiveTab;
        this.currentScrollTop = 0;
      }
    },
  },
};
</script>
<style lang="scss">
.city-list {
  display: flex;
  flex-direction: row;
  height: 100%;

  &-catalog {
    height: 100%;
    width: 104px;
    overflow-y: auto;

    /* N8 */
    background: #f7f9fc;

    .el-tabs {
      min-height: 100px;
    }

    .el-tabs--left .el-tabs__item.is-left {
      text-align: left !important;
    }

    .el-tabs__header {
      width: calc(100% - 1px);

      .el-tabs__item {
        /* Base/UI */
        font-family: "PingFang SC";
        font-style: normal;
        font-weight: 400;
        font-size: 14px;
        height: 36px;
        line-height: 36px;
        color: #1f264d;
        &.is-active {
          color: #2e57e5;
          font-weight: 600;
        }
      }
      .el-tabs__active-bar {
        background-color: #2e57e5;
      }
    }
    .el-tabs__content {
      display: none;
    }
  }
  &-content {
    flex: 1;
    height: calc(100% - 32px);
    overflow-y: auto;
    padding: 16px;

    &-section {
      width: 100%;
      height: fit-content;

      &-title {
        flex: 1;
        // height: 22px;

        /* N7 */
        background: #f3f5fa;
        border-radius: 2px;
        /* 文案 */
        font-family: "PingFang SC";
        font-style: normal;
        font-weight: 600;
        font-size: 16px;
        line-height: 20px;
        padding: 5px 2px;
        /* N1 */
        color: #1f264d;
        & > a {
          padding: 0 5px;
          border: 1px solid #f3f5fa;
        }
        a.selected,
        a.hover:hover {
          cursor: pointer;
          color: #2e57e5;
        }
        a.selected {
          border: 1px solid #c0caeb;
        }
      }
      &-content {
        padding: 5px 8px;
      }
      &-item {
        // width: 58px;
        height: 24px;
        line-height: 22px;
        border-radius: 2px;
        padding: 0px 6px;
        margin: 2px;
        text-align: center;
        display: inline-block;
        border: 1px solid #ffffff;
        color: #1f264d;
        font-family: "PingFang SC";
        font-style: normal;
        font-weight: 400;
        font-size: 14px;
        cursor: default;
        transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);

        &.selected,
        &.hover:hover {
          cursor: pointer;
          color: #2e57e5;
        }
        &.selected {
          border: 1px solid #c0caeb;
        }
      }
    }

    .warning {
      &.el-alert--warning.is-light {
        margin-bottom: 8px;
        background-color: #fce8d4;
        color: #f58718;
      }
      .el-alert__title {
        color: #1f264d;
      }
    }
  }
  &-no-data {
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -40px;
    margin-top: -40px;
    font-size: 80px;
    &-text {
      font-family: "PingFang SC";
      font-style: normal;
      font-weight: 400;
      font-size: 14px;
      text-align: center;
      /* N3 */
      color: #898ca3;
    }
  }
}
</style>
